package cmd

import (
	"svr/src/conf"
	"svr/src/msg"
	"svr/src/ws"

	"google.golang.org/protobuf/proto"
)

func init() {
	ws.AddHandler(&msg.RegisterDeviceR{}, handlerRegisterDeviceR)
	ws.AddHandler(&msg.RegisterDeviceA{}, handlerRegisterDeviceA)
	ws.AddHandler(&msg.NotifyAddServer{}, handlerNotifyAddServer)
}

func handlerRegisterDeviceR(mr proto.Message, task *ws.MsgTask) *msg.Error {
	msgR := mr.(*msg.RegisterDeviceR)
	// logs.Debugf("msg r", msgR)
	di := task.Dev
	di.Type = msgR.DevType
	msgA := &msg.RegisterDeviceA{
		DevType: conf.ServerConfig.ServerType,
		Balance: conf.ServerConfig.Balance,
	}
	switch di.Type {
	case msg.DeviceType_ClientGm, msg.DeviceType_ClientUser:
		{
			if conf.ServerConfig.ServerType == msg.DeviceType_SingleLogic { //单服模式，注册客户端
				ws.AddDeviceToMapGroup(di) //这里注册下面的设备上报的type
			} else { //多服模式
				switch conf.ServerConfig.Balance { //客户端只能连负载相关的服务器
				case msg.BalanceType_Alloc: //负载收集服，用来给第一个连到的客户端分配一个负载服
					{
						di, mer := ws.GetConnectDevice(msg.DeviceType_ServerTransmit, true) //!#//把转发服发给客户端，转发服有可能换
						if mer != nil {
							return mer
						}
						svr := &msg.ServerInfo{
							Type:       di.Type,
							AddrListen: di.AddrListen,
						}
						msgA.UpperServers = append(msgA.UpperServers, svr)
						break
					}
				case msg.BalanceType_Upload: //负载上报服，增加设备，
					{
						ws.AddDeviceToMapGroup(di) //这里注册下面的设备上报的type

						break
					}
				}
			}
			break
		}
	default:
		{
			ws.AddDeviceToMapGroup(di) //这里注册下面的设备上报的type
			if conf.IsTopServer() {    //顶级服务器，负责维护下面各个服务器之间的联系关系
				di.SetListenPort(msgR.ListenPort)            //给连进来的MsgR服务器的监听端口，进行设置
				msgA.UpperServers = ws.GetUpServers(di.Type) //告诉连进来的MsgR服务器，还需要连谁
				downDevices := ws.GetDownDevices(di.Type)    //告诉下面的服务器，谁需要连MsgR的服务器
				msgN := &msg.NotifyAddServer{
					Server: &msg.ServerInfo{
						Type:       di.Type,
						AddrListen: di.AddrListen,
					},
				}
				for _, dev := range downDevices {
					dev.SendMessageDirect(msgN)
				}
			}
			break
		}
	}
	return task.ReturnMsg(msgA)
	/**
	ws.AddDeviceToMapGroup(di) //这里获得下面的设备上报的type
	msgA := &msg.RegisterDeviceA{
		DevType: conf.ServerConfig.ServerType,
		Balance: conf.ServerConfig.Balance,
	}
	if di.Type == msg.DeviceType_ClientUser || di.Type == msg.DeviceType_ClientGm {
		if conf.ServerConfig.Balance == msg.BalanceType_Alloc {
			di, err := ws.GetConnectDevice(msg.DeviceType_ServerTransmit, true) //!#//把转发服发给客户端，转发服有可能换
			if xutil.CheckErr(err) {
				return err
			}
			svr := &msg.ServerInfo{
				Type:       di.Type,
				AddrListen: di.AddrListen,
			}
			msgA.UpperServers = append(msgA.UpperServers, svr)
		}
	} else {
		if conf.IsTopServer() {
			di.SetListenPort(msgR.ListenPort)            //给连进来的MsgR服务器的监听端口，进行设置
			msgA.UpperServers = ws.GetUpServers(di.Type) //告诉连进来的MsgR服务器，还需要连谁
			downDevices := ws.GetDownDevices(di.Type)    //告诉下面的服务器，谁需要连MsgR的服务器
			msgN := &msg.NotifyAddServer{
				Server: &msg.ServerInfo{
					Type:       di.Type,
					AddrListen: di.AddrListen,
				},
			}
			for _, dev := range downDevices {
				dev.SendMessage(msgN)
			}
		}
	}
	return task.ReturnMsg(msgA)
	/**/
}

func handlerRegisterDeviceA(mr proto.Message, task *ws.MsgTask) *msg.Error {
	msgA := mr.(*msg.RegisterDeviceA)
	di := task.Dev
	di.Type = msgA.DevType
	di.Blance = msgA.Balance
	ws.AddDeviceToMapGroup(di) //这里获得上面的设备下发的type
	_, err := di.SendMessageDirect(&msg.Ping{})
	if msgA.UpperServers != nil {
		for _, si := range msgA.UpperServers {
			go ws.ConnectToServer(si.AddrListen)
		}
	}
	return err
}

func handlerNotifyAddServer(mn proto.Message, task *ws.MsgTask) *msg.Error {
	msgN := mn.(*msg.NotifyAddServer) //接到通知要增加新服务器要连接
	go ws.ConnectToServer(msgN.Server.AddrListen)
	return nil
}
